package io.web.api;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import io.web.utils.BusinessException;
import io.web.utils.ErrorCode;
import io.web.utils.R;
import io.web.utils.SignUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Data
@Slf4j
public class ApiClient {

    private String url;

    public ApiClient(String url) {
        this.url = url;
    }

    public Object request(ApiClientVo clientVo) {
        // json body
        String json = clientVo.getBody();
        Map<String, String> headers = generateHeader(clientVo);
        // gateway url + api config path
        int index = clientVo.getUrl().indexOf("/api");
        if (index > -1) {
            index += 4;
        } else {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "接口地址未包含/api前缀");
        }
        HttpResponse response = HttpRequest.of(url + clientVo.getUrl().substring(index))
                .method(getMethod(clientVo.getMethod()))
                .body(json)
                .addHeaders(headers)
                .contentType("application/json;charset=utf-8")
                .execute();
        log.info("apiclient response = {}", response);
        if (response.getStatus() != HttpStatus.HTTP_OK) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String body = response.body();
        R<?> r = JSONUtil.toBean(body, R.class);
        return r.getData();
    }

    private Method getMethod(String method) {
        return Arrays.stream(Method.values())
                .filter(e -> e.name().equalsIgnoreCase(method))
                .findFirst().orElse(null);
    }

    private Map<String, String> generateHeader(ApiClientVo clientVo) {
        /*accessKey
         * data: request data
         * timestamp
         * nonce
         * sign*/
        String jsonData = clientVo.getBody().replaceAll("\\n", "");
        Map<String, String> headers = new HashMap<>();
        headers.put("accessKey", clientVo.getAccessKey());
        headers.put("data", jsonData);
        headers.put("timestamp", System.currentTimeMillis() + "");
        headers.put("nonce", IdUtil.getSnowflakeNextIdStr());
        headers.put("sign", SignUtils.sign(jsonData, clientVo.getSecretKey()));
        return headers;
    }

//    public String hello(HelloVo helloVo) {
//        String json = JSONUtil.toJsonStr(helloVo);
//        Map<String, String> headers = generateHeader(helloVo);
//        HttpResponse response = HttpRequest.post("http://localhost:8082/hello/post")
//                .body(json)
//                .addHeaders(headers)
//                .contentType("application/json;charset=utf-8")
//                .execute();
//        String body = response.body();
////        System.out.println("response = " + body);
//        return body;
//    }
//
//    private Map<String, String> generateHeader(HelloVo helloVo) {
//        /*accessKey
//         * data: request data
//         * timestamp
//         * nonce
//         * sign*/
//        String jsonData = JSONUtil.toJsonStr(helloVo);
//        Map<String, String> headers = new HashMap<>();
//        headers.put("accessKey", accessKey);
//        headers.put("data", jsonData);
//        headers.put("timestamp", System.currentTimeMillis() + "");
//        headers.put("nonce", IdUtil.randomUUID());
//        headers.put("sign", SignUtils.sign(jsonData, secretKey));
//        return headers;
//    }
}
